﻿using CodeGenerator.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml;

namespace CodeGenerator.Common
{
    public class Utils
    {
        public static readonly string DatabaseconfigPath = (Application.StartupPath + "/Config/databaseconfig.xml");
        private static Regex regSpace = new Regex(@"\s");
        public static string SysconfigPath = (Application.StartupPath + "/Config/sysconfig.xml");

        public static void AddConnection(Connection conection)
        {
            XmlDocument document = getXmlDocument();
            XmlNode node = document.SelectSingleNode("servers");
            XmlElement newChild = document.CreateElement("server");
            newChild.SetAttribute("id", conection.ID.ToString());
            newChild.SetAttribute("name", conection.Name);
            newChild.SetAttribute("database", conection.Database);
            newChild.SetAttribute("dbtype", conection.DbType);
            XmlElement element2 = document.CreateElement("connectionstring");
            XmlCDataSection section = document.CreateCDataSection(conection.ConnectionString);
            element2.AppendChild(section);
            newChild.AppendChild(element2);
            node.AppendChild(newChild);
            document.Save(DatabaseconfigPath);
        }

        public static void DeleteConnection(string id)
        {
            if (!string.IsNullOrEmpty(id))
            {
                XmlDocument document = getXmlDocument();
                XmlNodeList list = document.SelectNodes("servers/server");
                if ((list != null) && (list.Count > 0))
                {
                    foreach (XmlNode node in list)
                    {
                        if (node.Attributes["id"].Value.Trim().ToLower().Equals(id.Trim().ToLower()))
                        {
                            node.ParentNode.RemoveChild(node);
                            break;
                        }
                    }
                }
                document.Save(DatabaseconfigPath);
            }
        }

        public static DataTable GetColumnInfoDataTable(List<ColumnInfo> collist)
        {
            DataTable table = new DataTable();
            table.Columns.Add("ColumnSort");
            table.Columns.Add("ColumnName");
            table.Columns.Add("TypeName");
            table.Columns.Add("Length");
            table.Columns.Add("Precision");
            table.Columns.Add("Scale");
            table.Columns.Add("IsIdentity");
            table.Columns.Add("IsPrimaryKey");
            table.Columns.Add("IsColumnNull");
            table.Columns.Add("DefaultValue");
            table.Columns.Add("Description");
            foreach (ColumnInfo info in collist)
            {
                DataRow row = table.NewRow();
                row["ColumnSort"] = info.ColumnSort;
                row["ColumnName"] = info.ColumnName;
                row["TypeName"] = info.TypeName;
                row["Length"] = info.Length;
                row["Precision"] = info.Precision;
                row["Scale"] = info.Scale;
                row["IsIdentity"] = info.IsIdentity ? "√" : "";
                row["IsPrimaryKey"] = info.IsPrimaryKey ? "√" : "";
                row["IsColumnNull"] = info.IsColumnNull ? "√" : "";
                row["DefaultValue"] = info.DefaultValue;
                row["Description"] = info.Description;
                table.Rows.Add(row);
            }
            return table;
        }

        public static List<ColumnInfo> GetColumnInfos(DataTable dt)
        {
            List<ColumnInfo> list = new List<ColumnInfo>();
            if (dt == null)
            {
                return null;
            }
            foreach (DataRow row in dt.Rows)
            {
                string str = row["ColumnSort"].ToString();
                string str2 = row["ColumnName"].ToString();
                string str3 = row["TypeName"].ToString();
                string str4 = row["IsIdentity"].ToString();
                string str5 = row["IsPrimaryKey"].ToString();
                string str6 = row["Length"].ToString();
                string str7 = row["Precision"].ToString();
                string str8 = row["Scale"].ToString();
                string strA = row["IsColumnNull"].ToString();
                string str10 = row["DefaultValue"].ToString();
                string str11 = row["Description"].ToString();
                ColumnInfo item = new ColumnInfo
                {
                    ColumnSort = str,
                    ColumnName = str2,
                    TypeName = str3,
                    IsIdentity = str4 == "√",
                    IsPrimaryKey = str5 == "√",
                    Length = str6,
                    Precision = str7,
                    Scale = str8,
                    IsColumnNull = (strA == "√") || (string.Compare(strA, "Y", true) == 0),
                    DefaultValue = str10,
                    Description = str11
                };
                list.Add(item);
            }
            return list;
        }

        public static List<Connection> GetConnectionList()
        {
            List<Connection> list = new List<Connection>();
            XmlNodeList list2 = getXmlDocument().SelectNodes("servers/server");
            if ((list2 != null) && (list2.Count > 0))
            {
                foreach (XmlNode node in list2)
                {
                    if (node.HasChildNodes)
                    {
                        Connection item = new Connection
                        {
                            ID = new Guid(node.Attributes["id"].Value),
                            Name = node.Attributes["name"].Value,
                            Database = node.Attributes["database"].Value,
                            ConnectionString = node.FirstChild.InnerText,
                            DbType = node.Attributes["dbtype"].Value
                        };
                        list.Add(item);
                    }
                }
            }
            return list;
        }

        public static Connection GetConnectionModel(string id)
        {
            Connection connection = null;
            if (!string.IsNullOrEmpty(id))
            {
                XmlDocument document = new XmlDocument();
                document.Load(DatabaseconfigPath);
                XmlNode node = document.SelectSingleNode("servers/server[@id='" + id.ToString() + "']");
                if (node != null)
                {
                    connection = new Connection
                    {
                        ID = new Guid(node.Attributes["id"].Value),
                        Name = node.Attributes["name"].Value,
                        Database = node.Attributes["database"].Value,
                        ConnectionString = node.FirstChild.InnerText,
                        DbType = node.Attributes["dbtype"].Value
                    };
                }
            }
            return connection;
        }

        public static Sysconfig GetSysconfigModel()
        {
            Sysconfig sysconfig = new Sysconfig();
            XmlDocument document = new XmlDocument();
            document.Load(SysconfigPath);
            XmlNode node = document.SelectSingleNode("configs/config[@key='namespace']");
            if (node != null)
            {
                sysconfig.Namespace = node.FirstChild.InnerText;
            }
            node = document.SelectSingleNode("configs/config[@key='batchdirectorypath']");
            if (node != null)
            {
                sysconfig.BatchDirectoryPath = node.FirstChild.InnerText;
            }
            return sysconfig;
        }

        public static void GetSysconfigModel(Sysconfig sysconfigModel)
        {
            XmlDocument document = new XmlDocument();
            document.Load(SysconfigPath);
            XmlNode node = document.SelectSingleNode("configs/config[@key='namespace']");
            if (node != null)
            {
                node.FirstChild.Value = sysconfigModel.Namespace;
            }
            node = document.SelectSingleNode("configs/config[@key='batchdirectorypath']");
            if (node != null)
            {
                node.FirstChild.Value = sysconfigModel.BatchDirectoryPath;
            }
            document.Save(SysconfigPath);
        }

        private static XmlDocument getXmlDocument()
        {
            XmlDocument document = new XmlDocument();
            if (!File.Exists(DatabaseconfigPath))
            {
                File.WriteAllText(DatabaseconfigPath, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<servers>\n</servers>\n", Encoding.UTF8);
            }
            document.Load(DatabaseconfigPath);
            return document;
        }

        public static string ReadBatchDirectoryPath() =>
            GetSysconfigModel().BatchDirectoryPath;

        public static string ReadNamespace() =>
            GetSysconfigModel().Namespace;

        public static string ReplaceSpace(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return string.Empty;
            }
            char ch = value[0];
            if ((ch >= '0') && (ch <= '9'))
            {
                value = "_" + value;
            }
            return regSpace.Replace(value.Trim(), " ");
        }

        public static string ToCamelName(string name)
        {
            StringBuilder builder = new StringBuilder();
            if ((name == null) || string.IsNullOrEmpty(name))
            {
                return "";
            }
            if (!name.Contains("_"))
            {
                return (name.Substring(0, 1).ToUpper() + name.Substring(1).ToLower());
            }
            char[] separator = new char[] { '_' };
            string[] strArray = name.Split(separator);
            foreach (string str2 in strArray)
            {
                if (!string.IsNullOrEmpty(str2))
                {
                    builder.Append(str2.Substring(0, 1).ToUpper());
                    builder.Append(str2.Substring(1).ToLower());
                }
            }
            return builder.ToString();
        }

        public static string ToUpperFirstword(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return string.Empty;
            }
            return (value.Substring(0, 1).ToUpper() + value.Substring(1));
        }

        public static void WriteBatchDirectoryPath(string path)
        {
            XmlDocument document = new XmlDocument();
            document.Load(SysconfigPath);
            document.SelectSingleNode("configs/config[@key='batchdirectorypath']").FirstChild.Value = path;
            document.Save(SysconfigPath);
        }

        public static void WriteNamespace(string names)
        {
            XmlDocument document = new XmlDocument();
            document.Load(SysconfigPath);
            document.SelectSingleNode("configs/config[@key='namespace']").FirstChild.Value = names;
            document.Save(SysconfigPath);
        }

        /// <summary>
        /// 从资源文件中抽取资源文件
        /// </summary>
        /// <param name="resFileName">资源文件exe</param>
        public static void ExtractResFile(string resFileName, string outputFile)
        {
            Assembly assm = Assembly.LoadFrom(resFileName);
            HashSet<string> l_strHashType = new HashSet<string>();
            foreach (string resName in assm.GetManifestResourceNames())
            {
                Stream stream = assm.GetManifestResourceStream(resName);
                ResourceReader rr = new ResourceReader(stream);
                IDictionaryEnumerator enumerator = rr.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    DictionaryEntry de = (DictionaryEntry)enumerator.Current;
                    l_strHashType.Add(de.Value.GetType().ToString());

                    switch (de.Value.GetType().ToString())
                    {
                        case "System.Drawing.Icon":
                            System.Drawing.Icon ic = (Icon)de.Value;
                            //路径根据自己需要更改
                            using (System.IO.Stream sm = new FileStream(de.Key.ToString() + ".ico", FileMode.Create))
                            {
                                ic.Save(sm);
                            }

                            break;
                        case "System.Drawing.Bitmap":
                            System.Drawing.Bitmap icbmp = (Bitmap)de.Value;
                            icbmp.Save(de.Key.ToString() + ".bmp");
                            break;
                        case "System.Drawing.ImageListStreamer":
                            break;
                        default:
                            break;
                    }
                    //de.Key是资源名
                    //de.Value是资源内容
                }
            }
        }

        public static void MessageBoxShow(string content)
        {
            MessageBox.Show(content, "代码生成器V1.10");
        }

        public static DataTable CreateColumnTable()
        {
            DataTable table = new DataTable();
            DataColumn column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "ColumnSort"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "ColumnName"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "Description"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "TypeName"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "Length"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "Precision"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "Scale"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "IsIdentity"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "IsPrimaryKey"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "IsColumnNull"
            };
            table.Columns.Add(column);
            column = new DataColumn
            {
                DataType = Type.GetType("System.String"),
                ColumnName = "DefaultValue"
            };
            table.Columns.Add(column);
            return table;
        }

        public static DataTable GetKeyName( DataTable ColumnInfoList,DatabaseType databaseType)
        {
            DataTable table = CreateColumnTable();
            DataRow[] rowArray = null;
            if (databaseType == DatabaseType.SqlServer)
            {
                rowArray = ColumnInfoList.Select(" IsPrimaryKey='√' or IsIdentity='√' ");

            }
            else
            {
                 rowArray = ColumnInfoList.Select(" IsPrimaryKey='√' ");
            }
            foreach (DataRow row in rowArray)
            {
                DataRow row2 = table.NewRow();
                row2["ColumnSort"] = row["ColumnSort"];
                row2["ColumnName"] = row["ColumnName"];
                row2["TypeName"] = row["TypeName"];
                row2["Length"] = row["Length"];
                row2["Precision"] = row["Precision"];
                row2["Scale"] = row["Scale"];
                row2["IsIdentity"] = row["IsIdentity"];
                row2["IsPrimaryKey"] = row["IsPrimaryKey"];
                row2["IsColumnNull"] = row["IsColumnNull"];
                row2["DefaultValue"] = row["DefaultValue"];
                row2["Description"] = row["Description"];
                table.Rows.Add(row2);
            }
            return table;
        }
    }
}
